package br.eng.eliseu.gwt.aconchego.camera.client.ui.usuario;

import java.util.List;
import java.util.Set;

import br.eng.eliseu.gwt.aconchego.camera.client.service.UsuarioService;
import br.eng.eliseu.gwt.aconchego.camera.client.service.UsuarioServiceAsync;
import br.eng.eliseu.gwt.aconchego.camera.client.ui.component.EditAsyncCallback;
import br.eng.eliseu.gwt.aconchego.camera.module.AcessoCam;

import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

public class UsuarioList extends Composite {

	private static UsuarioListUiBinder uiBinder = GWT.create(UsuarioListUiBinder.class);
	interface UsuarioListUiBinder extends UiBinder<Widget, UsuarioList> {}
	
	private final UsuarioServiceAsync usuarioService = GWT.create(UsuarioService.class);
	private EditAsyncCallback<AcessoCam> callback;
	
	@UiField VerticalPanel usuarioListPanel;
	@UiField Button fecharButton;
	@UiField Button novoButton;
	@UiField Button excluiButton;

	@UiField VerticalPanel usuarioEditPanel;
	@UiField(provided=true) DataGrid<AcessoCam> usuariosDGrid ;
	
	private UsuarioEdit usuarioEdit;

	private ProvidesKey<AcessoCam> keyProviderUsuario;
	private TextColumn<AcessoCam> colNome;
	private TextColumn<AcessoCam> colGrupo;
	private TextColumn<AcessoCam> colStatus;

	private AcessoCam usuarioSelecionado = new AcessoCam();
	private AcessoCam usuarioLogin;
	
	public UsuarioList(AcessoCam usuarioLogin) {
		createTableUsuarios();
		initWidget(uiBinder.createAndBindUi(this));
		
		usuarioEdit = new UsuarioEdit(usuarioLogin);
		usuarioEditPanel.add(usuarioEdit);
		usuarioEditPanel.setVisible(false);
		
		this.setUsuarioLogin(usuarioLogin);
		
		setUsuarioSelecionado(null);
		populaTabelaAsync();
		
		
	}
	
	
	@UiHandler("fecharButton")
	void onFecharButtonClick(ClickEvent event) {
		if (getCallback()!=null){
			getCallback().onCancel();
		}

	}
	
	@UiHandler("novoButton")
	void onNovoButtonClick(ClickEvent event) {
		usuarioListPanel.setVisible(false);
		usuarioEditPanel.setVisible(true);
		usuarioEdit.setAcesso(new AcessoCam());
//		usuarioEdit = new UsuarioEdit(new AcessoCam(), new AcessoCam());
//		RootPanel.get().add(usuarioEdit);
		usuarioEdit.setCallback( new EditAsyncCallback<AcessoCam>() {

			public void onOk(AcessoCam ac) {
//				RootPanel.get().remove(usuarioEdit);
				usuarioEditPanel.setVisible(false);
				usuarioListPanel.setVisible(true);
				populaTabelaAsync();
			}

			public void onCancel() {
//				RootPanel.get().remove(usuarioEdit);
				usuarioEditPanel.setVisible(false);
				usuarioListPanel.setVisible(true);
			}

		} );

	}

	@UiHandler("excluiButton")
	void onExcluiButtonClick(ClickEvent event) {
		if (getUsuarioSelecionado() == null){
			Window.alert("Selecione um usuario!");
		} else { 
			if (Window.confirm("Confirma a exclusao do usuario "+getUsuarioSelecionado().getUsuario().getNome()+"?")){
				deletaUsuarioAsyn(getUsuarioSelecionado());
			}
		}
		
	}

	private void deletaUsuarioAsyn( AcessoCam usuarioDeleta){
		usuarioService.deletaUsuario( usuarioDeleta, new AsyncCallback<List<AcessoCam>>() {

			public void onSuccess(List<AcessoCam> usr) {
				usuariosDGrid.setRowData(usr);
			}

			public void onFailure(Throwable arg0) {
			}
			
		});
	}
	
	private void populaTabelaAsync(){
		usuarioService.listaUsuarios( new AsyncCallback<List<AcessoCam>>(){

			public void onSuccess(List<AcessoCam> usr) {
				usuariosDGrid.setRowData(usr);
			}
			
			public void onFailure(Throwable erro) {
				System.out.println(erro.getMessage());
			}
			
		});
	}
	
	private void editAcesso(AcessoCam acesso) {

		usuarioListPanel.setVisible(false);
		usuarioEditPanel.setVisible(true);
		usuarioEdit.setAcesso(acesso);
//		usuarioEdit = new UsuarioEdit(getUsuarioLogin(), acesso);
//		RootPanel.get().add(usuarioEdit);
		usuarioEdit.setCallback( new EditAsyncCallback<AcessoCam>() {

			public void onOk(AcessoCam ac) {
//				RootPanel.get().remove(usuarioEdit);
				usuarioEditPanel.setVisible(false);
				usuarioListPanel.setVisible(true);
				populaTabelaAsync();
			}

			public void onCancel() {
//				RootPanel.get().remove(usuarioEdit);
				usuarioEditPanel.setVisible(false);
				usuarioListPanel.setVisible(true);
			}

		} );
	}

	
	private void createTableUsuarios(){

		keyProviderUsuario = new ProvidesKey<AcessoCam>() {
			public Object getKey(AcessoCam item) {
				return (item.getUsuario().getId() == null) ? null : item.getUsuario().getId();
			}
		};
		usuariosDGrid = new DataGrid<AcessoCam>(keyProviderUsuario);
		usuariosDGrid.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);

		// --- Define modo de selecao
		final SingleSelectionModel<AcessoCam> selectionModel = new SingleSelectionModel<AcessoCam>(keyProviderUsuario);
		usuariosDGrid.setSelectionModel(selectionModel);
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			public void onSelectionChange(SelectionChangeEvent event) {
				Set<AcessoCam> s = selectionModel.getSelectedSet();
				if (s!=null){
					for (AcessoCam a : s) {
						if (a!=null){
							setUsuarioSelecionado((AcessoCam) a);
							break;
						}
					}
				}
			}
		});


		// --- Col id
		
		TextColumn<AcessoCam> colId = new TextColumn<AcessoCam>() {
		@Override
		public String getValue(AcessoCam object) {
				return String.valueOf(object.getUsuario().getId());
			}
		};
		colId.setSortable(true);
		usuariosDGrid.addColumn(colId, "Codigo");
		usuariosDGrid.setColumnWidth(colId, "10px" );

		// --- Col Nome
		colNome = new TextColumn<AcessoCam>() {
			@Override
			public String getValue(AcessoCam object) {
				return object.getUsuario().getNome();
			}
		};
		colNome.setSortable(true);
		usuariosDGrid.addColumn(colNome, "Nome");
		usuariosDGrid.setColumnWidth(colNome, "50px" );

		// --- Col Grupo
		colGrupo = new TextColumn<AcessoCam>() {
			@Override
			public String getValue(AcessoCam object) {
				return object.getGrupo().toString();
			}
		};
		colGrupo.setSortable(true);
		usuariosDGrid.addColumn(colGrupo, "Grupo");
		usuariosDGrid.setColumnWidth(colGrupo, "10px" );

		// --- Col Status
		colStatus = new TextColumn<AcessoCam>() {
			@Override
			public String getValue(AcessoCam object) {
				return object.getStatus().toString();
			}
		};
		colStatus.setSortable(true);
		usuariosDGrid.addColumn(colStatus, "Status");
		usuariosDGrid.setColumnWidth(colStatus, "10px" );


		// --- Botao Edit
		ActionCell<AcessoCam> actionEdit = new ActionCell<AcessoCam>("Editar", new ActionCell.Delegate<AcessoCam>() {
			public void execute(AcessoCam obj) {
				editAcesso(obj);
			}
		});
		Column<AcessoCam, AcessoCam> colEdit = new Column<AcessoCam, AcessoCam>(actionEdit){
			@Override
			public AcessoCam getValue(AcessoCam obj) {
				return obj;
			}
		};
		usuariosDGrid.addColumn(colEdit, "Editar");
		usuariosDGrid.setColumnWidth(colEdit, "30px" );


	}

	public EditAsyncCallback<AcessoCam> getCallback() {
		return callback;
	}


	public void setCallback(EditAsyncCallback<AcessoCam> callback) {
		this.callback = callback;
	}


	public AcessoCam getUsuarioLogin() {
		return usuarioLogin;
	}


	public void setUsuarioLogin(AcessoCam usuarioLogin) {
		this.usuarioLogin = usuarioLogin;
	}


	public AcessoCam getUsuarioSelecionado() {
		return usuarioSelecionado;
	}


	public void setUsuarioSelecionado(AcessoCam usuarioSelecionado) {
		this.usuarioSelecionado = usuarioSelecionado;
	}
}
